import org.bsc.langgraph4j.GraphStateException;
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.action.AsyncEdgeAction;
import org.bsc.langgraph4j.action.AsyncNodeAction;
import org.bsc.langgraph4j.action.EdgeAction;
import org.bsc.langgraph4j.action.NodeAction;
import org.bsc.langgraph4j.serializer.StateSerializer;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.state.AgentStateFactory;
import org.bsc.langgraph4j.utils.EdgeMappings;

import java.util.Objects;

import static org.bsc.langgraph4j.StateGraph.START;
import static org.bsc.langgraph4j.StateGraph.END;
import static org.bsc.langgraph4j.action.AsyncEdgeAction.edge_async;
import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;

/**
 * This is an automatically generated file. Do not modify it.
 *
 * This file was generated using `langgraph4j-gen`.
 */
public class {{name}}Builder<State extends AgentState> {

    {{#nodes}}
    private AsyncNodeAction<State> {{name}};
    {{/nodes}}
    {{#edges}}
    {{#condition}}
    private AsyncEdgeAction<State> {{condition}};
    {{/condition}}
    {{/edges}}

    {{#nodes}}
    public CustomAgentBuilderSample<State> {{name}}(AsyncNodeAction<State> {{name}}) {
        this.{{name}} = {{name}};
        return this;
    }
    {{/nodes}}
    {{#edges}}
    {{#condition}}
    public CustomAgentBuilderSample<State> {{condition}}(AsyncEdgeAction<State> {{condition}}) {
        this.{{condition}} = {{condition}};
        return this;
    }
    {{/condition}}
    {{/edges}}


    private StateGraph<State> of( AgentStateFactory<State> factory) {
        return new StateGraph<>( factory );
    }

    private StateGraph<State> of( StateSerializer<State> serializer) {
        return new StateGraph<>( serializer );
    }

    private StateGraph<State> of(Map<String, Channel<?>> channels, AgentStateFactory<State> factory) {
        return new StateGraph<>(factory);
    }

    private StateGraph<State> of(Map<String, Channel<?>> channels, StateSerializer<State> serializer) {
        return new StateGraph<>(serializer);
    }

    private StateGraph<State> build( StateGraph<State> graph ) throws GraphStateException {
        {{#nodes}}
        Objects.requireNonNull( {{name$}}, "{{name}} cannot be null");
        {{/nodes}}
        {{#edges}}
        {{#condition}}
        Objects.requireNonNull( {{condition}}, "{{condition}} cannot be null");
        {{/condition}}
        {{/edges}}

        return graph
        {{#nodes}}
            .addNode( {{name$}}, {{name}} )
        {{/nodes}}
        {{#edges}}
        {{^condition}}
            .addEdge( {{from$}}, {{to$}} )
        {{/condition}}
        {{#condition}}
            .addConditionalEdges( {{from$}},
                {{condition}},
                EdgeMappings.builder()
                {{#paths$}}
                    .to( {{.}} )
                {{/paths$}}
                .build())
        {{/condition}}
        {{/edges}}
        ;

    }

    public StateGraph<State> build( AgentStateFactory<State> factory ) throws GraphStateException {
        return build( of( factory ) );
    }

    public StateGraph<State> build( StateSerializer<State> serializer ) throws GraphStateException {
        return build( of( serializer ) );
    }

    public StateGraph<State> build(AgentStateFactory<State> factory, Map<String, Channel<?>> channels ) throws GraphStateException {
        return build(of( channels, factory ));
    }

    public StateGraph<State> build(Map<String, Channel<?>> channels, StateSerializer<State> serializer) throws GraphStateException {
        return build(of( channels, serializer ));
    }

}